package com.shirley.executor;

import com.shirley.callable.ShirleyCaller;
import com.shirley.thread.ShirleyThread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class ShirleyExecutor {

    private final static int corePoolSize = 2;
    private final static int maximumPoolSize = 3;
    private final static int capacity = 2;

    public static void main(String[] args) throws InterruptedException {
        startBySubmit();

        // execute不能获取到返回值和异常
//        startByExecute();

//        startByInvoke();
    }

    private static void startByInvoke() throws InterruptedException {
        ExecutorService threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(capacity), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        List<ShirleyCaller> callers = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            callers.add(new ShirleyCaller("Task" + i));
        }

        List<Future<String>> futures = new ArrayList<>();
        try {
            futures = threadPool.invokeAll(callers);
        } catch (Exception e) {
            System.out.println("Invoke task failed: " + e.getMessage());
        }
        System.out.println("All tasks invoked.");
        for (Future<String> f : futures) {
            try {
                String taskResult = f.get();
                System.out.println("taskResult = " + taskResult);
            } catch (Exception e) {
                System.out.println("Catch a exception from task." + e.getMessage());
            }
        }
        System.out.println("All tasks done.");
        threadPool.shutdown();
    }

    private static void startByExecute() throws InterruptedException {
        ExecutorService threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(capacity), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 10; i++) {
            try {
                // 假定所有Task execute，没有Task运行完成，则当 i > maximumPoolSize + capacity -1 时，由于指定的拒绝策略时AbortPolicy，新提交的task将会被拒绝，并抛异常
                threadPool.execute(new ShirleyThread("Task" + i));
            } catch (Exception e) {
                System.out.println("Execute task " + i + " failed: " + e.getMessage());
            }
        }

        threadPool.shutdown();
        System.out.println("Tasks executed.");

        threadPool.awaitTermination(100, TimeUnit.MINUTES);
        System.out.println("All tasks terminated.");

    }

    private static void startBySubmit() throws InterruptedException {
        ExecutorService threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(capacity), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

        List<Future<String>> futures = new ArrayList<>();
        for (int i = 1; i < 10; i++) {
            try {
                // 假定所有Task submit前，没有Task运行完成，则当 i > + maximumPoolSize + capacity -1时，由于指定的拒绝策略时AbortPolicy，新提交的task将会被拒绝，并抛异常
                Future<String> future = threadPool.submit(new ShirleyCaller("Task" + i));
                futures.add(future);
            } catch (Exception e) {
                System.out.println("Submit task " + i + " failed: " + e.getMessage());
            }
        }
        threadPool.shutdown();
        System.out.println("Tasks submitted");
        threadPool.awaitTermination(100, TimeUnit.MINUTES);
        System.out.println("All tasks terminated.");

        for (Future<String> f : futures) {
            try {
                String taskResult = f.get();
                System.out.println("taskResult = " + taskResult);
            } catch (Exception e) {
                System.out.println("Catch a exception from task." + e.getMessage());
            }

        }

    }
}
